import os
from fastapi import APIRouter, Body, FastAPI, File, Form, Header, Query,Depends, Request, Response, UploadFile, HTTPException, status
from fastapi.responses import StreamingResponse
from app.utils.logger import get_logger
from app.api.api_model import SuccessResponse, ErrorResponse, FileResponse
from app.db.db_resources import DBResources
from sqlalchemy.orm import Session
from app.db.db_handler import get_db
from db.db_file import DBFile, get_video_path
import re

logger = get_logger()

router = APIRouter(
    prefix="/restful",
    tags=["restful V1"],
)

db_dict = dict()

@router.get("/resources", summary="获取资源信息")
async def get_resources():
    db_resources: DBResources = db_dict["Resources"]
    resources = db_resources.get_resources()
    return SuccessResponse(data={"desc":"获取资源信息","version": "1.0.0","resources": resources})

@router.get("/resources/{resource_id}", summary="获取单个资源信息使用路径参数")
async def get_single_resource(resource_id: int):
    db_resources: DBResources = db_dict["Resources"]
    resources = db_resources.get_resources(resource_id)
    return SuccessResponse(data={"desc":"获取单个资源信息使用路径参数","version": "1.0.0","resources": resources})

@router.get("/resourcesbyquery", summary="获取单个资源信息使用查询参数")
async def get_single_resource_by_query(resource_id: int = Query(None, description="资源ID")):
    db_resources: DBResources = db_dict["Resources"]
    resources = db_resources.get_resources(resource_id)
    return SuccessResponse(data={"desc":"获取单个资源信息使用查询参数","version": "1.0.0","resources": resources})


@router.post("/resourcesbybody", summary="添加资源信息使用Body")
async def add_resource_by_query(name:str = Body(..., description="资源名称"), user_id:int = Body(..., description="用户ID")):
    db_resources: DBResources = db_dict["Resources"]
    db_resources.add_resource(name, user_id)
    return SuccessResponse(data={"desc":"添加资源信息使用Body，application/json","version": "1.0.0","resources": {"name": name, "user_id": user_id}})

@router.post("/resourcesbyform", summary="添加资源信息使用Form")
async def add_resource_by_form(name:str = Form(..., description="资源名称"), user_id:int = Form(..., description="用户ID")):
    db_resources: DBResources = db_dict["Resources"]
    db_resources.add_resource(name, user_id)
    return SuccessResponse(data={"desc":"添加资源信息使用Form，x-www-form-urlenconde","version": "1.0.0","resources": {"name": name, "user_id": user_id}})

@router.post("/resourcesbyraw", summary="添加资源信息使用raw")
async def add_resource_by_raw(request: Request):
    # 读取原始请求体
    raw_body = await request.body()
    raw_body = raw_body.decode('utf-8')
    name, user_id = raw_body.split(',')
    db_resources: DBResources = db_dict["Resources"]
    db_resources.add_resource(name, user_id)
    return SuccessResponse(data={"desc":"添加资源信息使用raw","version": "1.0.0","resources": {"name": name, "user_id": user_id}})

@router.put("/resources/{resource_id}", summary="更新资源信息使用路径参数")
async def update_resource(resource_id: int, name:str = Body(..., description="资源名称"), user_id:int = Body(..., description="用户ID")):
    db_resources: DBResources = db_dict["Resources"]
    db_resources.update_resource(resource_id, name, user_id)
    return SuccessResponse(data={"desc":"更新资源信息使用路径参数","version": "1.0.0","resources": {"name": name, "user_id": user_id}})

@router.delete("/resources/{resource_id}", summary="删除资源信息使用路径参数")
async def delete_resource(resource_id: int):
    db_resources: DBResources = db_dict["Resources"]
    db_resources.delete_resource(resource_id)
    return SuccessResponse(data={"desc":"删除资源信息使用路径参数","version": "1.0.0","resources": {"resource_id": resource_id}})

@router.post("/files/upload", summary="上传文件")
async def upload_file(file: UploadFile = File(...)):
    db_file: DBFile = db_dict["File"]
    file_model = db_file.upload_file(file)
    return SuccessResponse(data={"desc":"上传文件","version": "1.0.0","file_name": file_model.filename})

@router.get("/files/download", summary="下载文件")
async def download_file(file_name: str):
    db_file: DBFile = db_dict["File"]
    file_data = db_file.download_file(file_name)
    if file_data:
        return FileResponse(data={"desc":"下载文件","version": "1.0.0","file_name": file_name, "file_data": file_data})
    return ErrorResponse(data={"desc":"文件不存在","version": "1.0.0","file_name": file_name})

# # 视频流
# VIDEO_DIR = "video"

# # 确保视频目录存在
# os.makedirs(VIDEO_DIR, exist_ok=True)

@router.post("/upload_video/")
async def upload_video(file: UploadFile = File(...)):
    file_location = get_video_path(video_id=file.filename)
    with open(file_location, "wb") as video_file:
        video_file.write(await file.read())
    return SuccessResponse(data={"desc":"上传视频","version": "1.0.0","file_name": file.filename})

# @router.get("/stream_video/{video_name}")
# async def stream_video(video_name: str):
#     video_path = os.path.join(VIDEO_DIR, video_name)
#     if not os.path.exists(video_path):
#         return ErrorResponse(data={"desc":"视频不存在","version": "1.0.0","video_name": video_name})

#     def video_stream():
#         with open(video_path, "rb") as video_file:
#             while chunk := video_file.read(1024):  # 逐块读取视频
#                 yield chunk

#     return StreamingResponse(video_stream(), media_type="video/mp4")

# @router.post("/resources", summary="添加资源信息使用Query")
# async def add_resource(name:str = Query(..., description="资源名称"), user_id:int = Query(..., description="用户ID")):
#     db_resources: DBResources = db_dict["Resources"]
#     db_resources.add_resource(name, user_id)
#     return SuccessResponse(data={"desc":"添加资源信息使用Query","version": "1.0.0","resources": {"name": name, "user_id": user_id}})

# @router.post("/resources", summary="添加资源信息使用Header"):
# async def add_resource(name:str = Header(..., description="资源名称"), user_id:int = Header(..., description="用户ID")):
#     db_resources: DBResources = db_dict["Resources"]
#     db_resources.add_resource(name, user_id)
#     return SuccessResponse(data={"desc":"添加资源信息使用Header","version": "1.0.0","resources": {"name": name, "user_id": user_id}})

# @router.post("/resources", summary="添加资源信息使用Cookie"):
# async def add_resource(name:str = Cookie(..., description="资源名称"), user_id:int = Cookie(..., description="用户ID")):
#     db_resources: DBResources = db_dict["Resources"]
#     db_resources.add_resource(name, user_id)
#     return SuccessResponse(data={"desc":"添加资源信息使用Cookie","version": "1.0.0","resources": {"name": name, "user_id": user_id}})

# @router.post("/resources", summary="添加资源信息使用Path"):
# async def add_resource(name:str = Path(..., description="资源名称"), user_id:int = Path(..., description="用户ID")):
#     db_resources: DBResources = db_dict["Resources"]
#     db_resources.add_resource(name, user_id)
#     return SuccessResponse(data={"desc":"添加资源信息使用Path","version": "1.0.0","resources": {"name": name, "user_id": user_id}}) 

# @router.post("/resources", summary="添加资源信息使用Security"):
# async def add_resource(name:str = Security(..., description="资源名称"), user_id:int = Security(..., description="用户ID")):
#     db_resources: DBResources = db_dict["Resources"]
#     db_resources.add_resource(name, user_id)
#     return SuccessResponse(data={"desc":"添加资源信息使用Security","version": "1.0.0","resources": {"name": name, "user_id": user_id}})

# 添加视频流接口
@router.get("/videos/{video_id}", summary="观看视频")
async def stream_video(video_id: str, request: Request):
    """
    视频流接口，支持 Range 请求头，实现视频的分段传输
    """
    video_path = get_video_path(video_id)
    if not video_path or not video_path.exists():
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="视频未找到")

    file_size = video_path.stat().st_size
    range_header = request.headers.get("Range", None)
    if range_header:
        byte1, byte2 = 0, None
        m = re.search(r"bytes=(\d+)-(\d*)", range_header)
        if m:
            g = m.groups()
            byte1 = int(g[0])
            if g[1]:
                byte2 = int(g[1])
        chunk_size = 1024 * 1024  # 1MB
        byte2 = byte2 or byte1 + chunk_size
        if byte2 > file_size - 1:
            byte2 = file_size - 1
        length = byte2 - byte1 + 1
        with open(video_path, "rb") as f:
            f.seek(byte1)
            data = f.read(length)
        headers = {
            "Content-Range": f"bytes {byte1}-{byte2}/{file_size}",
            "Accept-Ranges": "bytes",
            "Content-Length": str(length),
            "Content-Type": "video/mp4",
        }
        return StreamingResponse(iter([data]), status_code=status.HTTP_206_PARTIAL_CONTENT, headers=headers)
    else:
        return StreamingResponse(open(video_path, "rb"), media_type="video/mp4")
 
